package com.hdu.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.hdu.entity.*;
import com.hdu.entity.SchoolScore;
import com.hdu.mapper.*;
import com.hdu.pojo.DataCell;
import com.hdu.pojo.PageBean;
import com.hdu.service.ISchoolService;
import com.hdu.vo.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 学校实体类 服务实现类
 * </p>
 *
 * @author xiaobai
 * @since 2023-10-28
 */

@Service
@RequiredArgsConstructor
public class SchoolServiceImpl extends ServiceImpl<SchoolMapper, School> implements ISchoolService {

    private final SchoolMajorMapper schoolMajorMapper;

    private final SchoolScoreMapper schoolScoreMapper;

    private final HireScoreMapper hireScoreMapper;

    private final SchoolMapper schoolMapper;

    private final EnrollMapper enrollMapper;

    private final MajorMapper majorMapper;

    private final JSONObject regionJson = JSONObject.parseObject("{44:\"广东\",22:\"吉林\",23:\"黑龙江\",45:\"广西\",46:\"海南\",50:\"重庆\",51:\"四川\",52:\"贵州\",53:\"云南\",31:\"上海\",32:\"江苏\",54:\"西藏\",11:\"北京\",33:\"浙江\",34:\"安徽\",12:\"天津\",35:\"福建\",13:\"河北\",36:\"江西\",14:\"山西\",37:\"山东\",15:\"内蒙古\",61:\"陕西\",62:\"甘肃\",41:\"河南\",63:\"青海\",42:\"湖北\",64:\"宁夏\",43:\"湖南\",21:\"辽宁\",65:\"新疆\",81:\"香港\",82:\"澳门\"}");

    private final JSONObject batchJson = JSONObject.parseObject("{1564:\"本科一段\",2935:\"第二批\",2674:\"本科第二批\",17:\"平行录取二段\",52:\"本科一批B段\",1561:\"艺术类本科批\",37:\"本科提前批B段\",2777:\"艺术类本科A段\",113:\"本科二批K段\",51:\"本科一批A段\",86:\"本科提前批C段\",1534:\"本科二批及预科\",2726:\"体育类本科批\",8:\"本科二批\",36:\"本科提前批A段\",119:\"高职（专科）批R段\",10:\"专科批\",2929:\"艺术本科二批\",1565:\"本科二段\",16:\"平行录取一段\",2642:\"本科第一批\",2699:\"艺术本科提前批B段\",6:\"本科提前批\",98:\"本科一批A1段\",48:\"专科批A段\",12:\"国家专项计划本科批\",2741:\"艺术类第二批\",2685:\"本科一批U段\",2915:\"艺术类第一批A段\",69:\"本科综合评价批\",1570:\"普通类一段\",15:\"普通类提前批\",2949:\"本科一批T段\",13:\"地方专项计划本科批\",1137:\"高校专项计划本科批\",2583:\"艺术本科A段\",2668:\"艺术本科批B段\",47:\"本科批B段\",2669:\"艺术本科批C段\",46:\"本科批A段\",14:\"本科批\",44:\"本科二批A段\",2667:\"艺术本科批A段\",45:\"本科二批B段\",54:\"本科二批C段\",111:\"本科一批I段\",11:\"专科提前批\",1571:\"普通类二段\",2734:\"体育类第一段\",1939:\"普通类平行录取\",90:\"特殊类型招生批\",7:\"本科一批\"}");

    private final JSONObject typeJson = JSONObject.parseObject("{33:\"蒙授理科\",1157:\"医学类\",24:\"体育理\",2:\"文科\",1085:\"学考理\",1079:\"3+证书\",1144:\"计算机类\",1150:\"旅游类\",26:\"艺术理\",1145:\"农学类\",2295:\"体育类（物理）\",1151:\"汽驾类\",2234:\"学考\",1148:\"财会类\",1156:\"幼师类\",3:\"综合\",1:\"理科\",2074:\"历史类\",23:\"体育文\",5:\"体育类\",2294:\"体育类（历史）\",1084:\"学考文\",1147:\"烹饪类\",32:\"蒙授文科\",1152:\"建筑类\",25:\"艺术文\",31:\"蒙授体育\",4:\"艺术类\",2073:\"物理类\",2293:\"艺术类（物理）\",2292:\"艺术类（历史）\"}");

    @Override
    public List<SchoolTable> hotSchool(Integer type) {
        String[] att = {"duality", "admission", "level"};
        Object[] obj = {1, 1, "专科（高职）"};
        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.eq(att[type], obj[type]);
        List<School> schoolList = list(wrapper.isNotNull("rate_rank").orderByAsc("rate_rank").last("limit 10"));
        return BeanUtil.copyToList(schoolList, SchoolTable.class);
    }

    @Override
    public PageBean<SchoolList> schoolPage(Integer current, Integer size, String level, String region, String type, String special, String name) {

        Page<School> page = new Page<>(current, size);

        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.eq(StrUtil.isNotEmpty(special), special, 1)
                .eq(StrUtil.isNotEmpty(level), "level", level)
                .eq(StrUtil.isNotEmpty(region), "province", region)
                .likeRight(StrUtil.isNotEmpty(type), "type", type)
                .like(StrUtil.isNotEmpty(name), "name", name)
                .orderByAsc("rate_rank");

        IPage<School> iPage = schoolMapper.selectPage(page, wrapper);

        return new PageBean<>(iPage.getTotal(), BeanUtil.copyToList(iPage.getRecords(), SchoolList.class));
    }

    public PageBean<SchoolList> schoolRank(Integer current, Integer size, Integer type) {

        String[] arr = {"ruan_rank", "xyh_rank", "us_rank", "qs_rank", "tws_china", "tws_world"};
        Page<School> page = new Page<>(current, size);

        QueryWrapper<School> wrapper = new QueryWrapper<>();
        wrapper.isNotNull(arr[type]).last("order by  CAST(" + arr[type] + " AS UNSIGNED)");

        IPage<School> iPage = schoolMapper.selectPage(page, wrapper);

        List<SchoolList> schoolLists = BeanUtil.copyToList(iPage.getRecords(), SchoolList.class);

        for (SchoolList schoolList : schoolLists) {
            wrapper = new QueryWrapper<>();
            wrapper.eq("id", schoolList.getId()).select(arr[type]);
            schoolList.setRank((String) schoolMapper.selectObjs(wrapper).get(0));
        }

        return new PageBean<>(iPage.getTotal(), schoolLists);
    }

    @Override
    public PageBean<SchoolSpecial> special(Integer current, Integer size, String id, String name, String type) {

        IPage<SchoolSpecial> iPage = majorMapper.selectJoinPage(new Page<>(current, size), SchoolSpecial.class,
                new MPJLambdaWrapper<Major>()
                        .selectAll(Major.class)
                        .select(SchoolMajor::getIsNation)
                        .rightJoin(SchoolMajor.class, SchoolMajor::getMajorId, Major::getId)
                        .like(StrUtil.isNotEmpty(name), Major::getName, name)
                        .eq(StrUtil.isNotEmpty(type), Major::getType, type)
                        .eq(SchoolMajor::getSchoolId, id));

        return new PageBean<>(iPage.getTotal(), iPage.getRecords());
    }

    @Override
    public SchoolView overview(String id) {
        SchoolView schoolView = BeanUtil.copyProperties(getById(id), SchoolView.class);
        QueryWrapper<SchoolMajor> query = new QueryWrapper<>();
        query.eq("school_id", id).eq("is_nation", 1).select("major_id");
        QueryWrapper<Major> wrapper = new QueryWrapper<>();
        if (schoolMajorMapper.selectObjs(query).size() != 0) {
            wrapper.in("id", schoolMajorMapper.selectObjs(query)).select("name");
            schoolView.setAttrList(majorMapper.selectObjs(wrapper));
        }
        return schoolView;
    }

    @Override
    public List<String> specialType(String id) {
        return majorMapper.specialType(id);
    }

    @Override
    public PageBean<EnrollTable> enroll(Integer current, Integer size, Integer id, Integer region, Integer batch, Integer type) {
        Page<Enroll> page = new Page<>(current, size);

        QueryWrapper<Enroll> wrapper = new QueryWrapper<>();

        wrapper.eq(region != null, "region", region)
                .eq(type != null, "type", type)
                .eq(id != null, "school_id", id)
                .eq(batch != null, "batch", batch);

        IPage<Enroll> iPage = enrollMapper.selectPage(page, wrapper);

        return new PageBean<>(iPage.getTotal(), BeanUtil.copyToList(iPage.getRecords(), EnrollTable.class));
    }

    @Override
    public List<EnrollSelect> enrollSelect(String id) {
        List<EnrollSelect> selectList = new ArrayList<>();
        QueryWrapper<Enroll> wrapperRegion = new QueryWrapper<>();
        wrapperRegion.select("region").eq("school_id", id).last("group by region");
        for (Object region : enrollMapper.selectObjs(wrapperRegion)) {
            EnrollSelect enrollSelect = new EnrollSelect();
            enrollSelect.setRegion(DataCell.of(regionJson.getString(String.valueOf(region)), region));
            QueryWrapper<Enroll> wrapperBatch = new QueryWrapper<>();
            wrapperBatch.select("batch").eq("school_id", id).eq("region", region).last("group by batch");
            List<DataCell> batchList = new ArrayList<>();
            for (Object batch : enrollMapper.selectObjs(wrapperBatch)) {
                batchList.add(DataCell.of(batchJson.getString(String.valueOf(batch)), batch));
            }
            enrollSelect.setBatch(batchList);
            QueryWrapper<Enroll> wrapperType = new QueryWrapper<>();
            wrapperType.select("type").eq("school_id", id).eq("region", region).last("group by type");
            List<DataCell> typeList = new ArrayList<>();
            for (Object type : enrollMapper.selectObjs(wrapperType)) {
                typeList.add(DataCell.of(typeJson.getString(String.valueOf(type)), type));
            }
            enrollSelect.setType(typeList);
            selectList.add(enrollSelect);
        }
        return selectList;
    }

    @Override
    public List<HireTable> hire(Integer id, Integer region, String year, Integer type) {

        QueryWrapper<HireScore> wrapper = new QueryWrapper<>();

        wrapper.eq(region != null, "region", region)
                .eq(type != null, "type", type)
                .eq(id != null, "school_id", id)
                .eq(StrUtil.isNotEmpty(year), "year", year);


        return BeanUtil.copyToList(hireScoreMapper.selectList(wrapper), HireTable.class);
    }

    @Override
    public List<HireSelect> hireSelect(String id) {
        List<HireSelect> selectList = new ArrayList<>();
        QueryWrapper<HireScore> wrapperRegion = new QueryWrapper<>();
        wrapperRegion.select("region").eq("school_id", id).last("group by region");
        for (Object region : hireScoreMapper.selectObjs(wrapperRegion)) {
            HireSelect hireSelect = new HireSelect();
            hireSelect.setRegion(DataCell.of(regionJson.getString(String.valueOf(region)), region));

            QueryWrapper<HireScore> wrapperYear = new QueryWrapper<>();
            wrapperYear.select("year").eq("school_id", id).eq("region", region).last("group by year order by year desc");
            List<HireCell> hireCellList = new ArrayList<>();
            for (Object year : hireScoreMapper.selectObjs(wrapperYear)) {
                QueryWrapper<HireScore> wrapperType = new QueryWrapper<>();
                wrapperType.select("type").eq("school_id", id).eq("year", year).eq("region", region).last("group by type");
                List<DataCell> typeList = new ArrayList<>();
                for (Object type : hireScoreMapper.selectObjs(wrapperType)) {
                    typeList.add(DataCell.of(typeJson.getString(String.valueOf(type)), type));
                }
                hireCellList.add(new HireCell(typeList, year));
            }
            hireSelect.setCell(hireCellList);
            selectList.add(hireSelect);
        }
        return selectList;
    }

    @Override
    public PageBean<ScoreTable> score(Integer current, Integer size, Integer id, Integer region, Integer batch, Integer type, String year) {
        Page<SchoolScore> page = new Page<>(current, size);

        QueryWrapper<SchoolScore> wrapper = new QueryWrapper<>();

        wrapper.eq(region != null, "region", region)
                .eq(type != null, "type", type)
                .eq(id != null, "school_id", id)
                .eq(batch != null, "batch", batch)
                .eq(StrUtil.isNotEmpty(year), "year", year);

        IPage<SchoolScore> iPage = schoolScoreMapper.selectPage(page, wrapper);

        return new PageBean<>(iPage.getTotal(), BeanUtil.copyToList(iPage.getRecords(), ScoreTable.class));
    }

    @Override
    public List<ScoreSelect> scoreSelect(String id) {
        List<ScoreSelect> selectList = new ArrayList<>();
        QueryWrapper<SchoolScore> wrapperRegion = new QueryWrapper<>();
        wrapperRegion.select("region").eq("school_id", id).last("group by region");
        for (Object region : schoolScoreMapper.selectObjs(wrapperRegion)) {
            ScoreSelect scoreSelect=new ScoreSelect();
            scoreSelect.setRegion(DataCell.of(regionJson.getString(String.valueOf(region)), region));

            QueryWrapper<SchoolScore> wrapperYear = new QueryWrapper<>();
            wrapperYear.select("year").eq("school_id", id).eq("region", region).last("group by year order by year desc");
            List<ScoreCell> scoreCellList = new ArrayList<>();
            for (Object year : schoolScoreMapper.selectObjs(wrapperYear)) {
                QueryWrapper<SchoolScore> wrapperType = new QueryWrapper<>();
                QueryWrapper<SchoolScore> wrapperBatch = new QueryWrapper<>();
                List<DataCell> typeList = new ArrayList<>();
                List<DataCell> batchList = new ArrayList<>();
                wrapperType.select("type").eq("school_id", id).eq("year", year).eq("region", region).last("group by type");
                wrapperBatch.select("batch").eq("school_id", id).eq("year", year).eq("region", region).last("group by batch");
                for (Object type : schoolScoreMapper.selectObjs(wrapperType)) {
                    typeList.add(DataCell.of(typeJson.getString(String.valueOf(type)), type));
                }
                for (Object batch : schoolScoreMapper.selectObjs(wrapperBatch)) {
                    batchList.add(DataCell.of(batchJson.getString(String.valueOf(batch)), batch));
                }
                scoreCellList.add(new ScoreCell(typeList, batchList, year));
            }
            scoreSelect.setCell(scoreCellList);
            selectList.add(scoreSelect);
        }
        return selectList;
    }
}
